package com.cmc.cloud.cmclink.doc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.cmc.cloud.cmclink.doc.api.document.emums.RecordStatusEnum;
import com.cmc.cloud.cmclink.doc.constants.errorconstant.TblisustampFilesErrorCodeConstants;
import com.cmc.cloud.cmclink.doc.dto.RecordStatusDto;
import com.cmc.cloud.cmclink.doc.entity.TblisustampFilesDO;
import com.cmc.cloud.cmclink.doc.entity.TblisustampMainDO;
import com.cmc.cloud.cmclink.doc.mapper.TblisustampFilesMapper;
import com.cmc.cloud.cmclink.doc.mapper.TblisustampMainMapper;
import com.cmc.cloud.cmclink.doc.service.TblisustampFilesService;
import com.cmc.cloud.cmclink.doc.vo.tblisustampfiles.TblisustampFilesApproveRespVO;
import com.cmc.cloud.cmclink.doc.vo.tblisustampfiles.TblisustampFilesCreateReqVO;
import com.cmc.cloud.cmclink.doc.vo.tblisustampfiles.TblisustampFilesPageReqVO;
import com.cmc.cloud.cmclink.doc.vo.tblisustampfiles.TblisustampFilesUpdateReqVO;
import com.cmes.framework.common.exception.util.ServiceExceptionUtil;
import com.cmes.framework.common.pojo.PageResult;
import com.cmes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cmes.platform.bpm.biz.app.BpmProcessInstanceAppService;
import com.cmes.platform.bpm.service.definition.BpmProcessDefinitionService;
import com.cmes.platform.system.nuc.NucApi;
import com.cmes.platform.system.nuc.dto.UserProfileDTO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import static com.cmc.cloud.cmclink.doc.api.document.emums.RecordStatusEnum.*;


/**
 * 申请明细信息 Service 实现类
 *
 * @author 集运管理员
 */
@Service
@Validated
public class TblisustampFilesServiceImpl implements TblisustampFilesService {

    @Resource
    private TblisustampFilesMapper tblisustampFilesMapper;

    @Resource
    private TblisustampMainMapper tblisustampMainMapper;

    @Resource
    BpmProcessInstanceAppService bpmProcessInstanceAppService;

    @Resource
    BpmProcessDefinitionService bpmProcessDefinitionService;

    @Resource
    private NucApi nucApi;

    /**
     * 工作流流程标识key
     */
    public static final String PROCESS_KEY = "FILE-APPROVE";

    @Override
    public void createTblisustampFiles(TblisustampFilesCreateReqVO createReqVO) {
        // 插入
        TblisustampFilesDO tblisustampFiles = BeanUtil.copyProperties(createReqVO, TblisustampFilesDO.class);
        tblisustampFiles.setRecordStatus(PENDING_SUBMIT.getValue());
        tblisustampFilesMapper.insert(tblisustampFiles);
    }

    @Override
    public void updateTblisustampFiles(TblisustampFilesUpdateReqVO updateReqVO) {
        // 校验存在
        validateTblisustampFilesExists(updateReqVO.getId());
        // 更新
        TblisustampFilesDO updateObj = BeanUtil.copyProperties(updateReqVO, TblisustampFilesDO.class);
        tblisustampFilesMapper.updateById(updateObj);
    }

    @Override
    public void deleteTblisustampFiles(Long id) {
        // 校验存在
        TblisustampFilesDO tblisustampFilesDO = validateTblisustampFilesExists(id);
        if (PENDING_SUBMIT.getValue() != tblisustampFilesDO.getRecordStatus() && CANCEL.getValue() != tblisustampFilesDO.getRecordStatus()) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_NOT_DELETE);
        }
        // 删除
        tblisustampFilesMapper.deleteById(id);
    }

    private TblisustampFilesDO validateTblisustampFilesExists(Long id) {
        TblisustampFilesDO tblisustampFilesDO = tblisustampFilesMapper.selectById(id);
        if (tblisustampFilesMapper.selectById(id) == null) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.TBLISUSTAMP_FILES_NOT_EXISTS);
        }
        return tblisustampFilesDO;
    }

    @Override
    public TblisustampFilesDO getTblisustampFiles(Long id) {
        return tblisustampFilesMapper.selectById(id);
    }

    @Override
    public TblisustampFilesApproveRespVO getTblisustampApproveFiles(Long id) {
        TblisustampFilesDO tblisustampFilesDO = tblisustampFilesMapper.selectById(id);
        if (tblisustampFilesDO == null) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.TBLISUSTAMP_FILES_NOT_EXISTS);
        }
        TblisustampFilesApproveRespVO tblisustampFilesApproveRespVO = BeanUtil.copyProperties(tblisustampFilesDO, TblisustampFilesApproveRespVO.class);
        TblisustampMainDO tblisustampMainDO = tblisustampMainMapper.selectById(tblisustampFilesDO.getMainId());
        tblisustampFilesApproveRespVO.setAgentCode(tblisustampMainDO.getAgentCode());
        tblisustampFilesApproveRespVO.setPolCode(tblisustampMainDO.getPortCode());
        tblisustampFilesApproveRespVO.setRemark(tblisustampMainDO.getRemark());
        return tblisustampFilesApproveRespVO;
    }

    @Override
    public List<TblisustampFilesDO> getTblisustampFilesList(Collection<Long> ids) {
        return tblisustampFilesMapper.selectBatchIds(ids);
    }

    @Override
    public List<TblisustampFilesDO> getListByMainId(Long id) {
        List<TblisustampFilesDO> list = tblisustampFilesMapper.selectList(new LambdaQueryWrapper<TblisustampFilesDO>().eq(TblisustampFilesDO::getMainId, id));
        return list;
    }

    @Override
    public PageResult<TblisustampFilesDO> getTblisustampFilesPage(TblisustampFilesPageReqVO reqVO) {
        LambdaQueryWrapperX<TblisustampFilesDO> itemQuery = new LambdaQueryWrapperX<TblisustampFilesDO>()
                .likeIfPresent(TblisustampFilesDO::getRecordStatus, reqVO.getKeyWord());

        LambdaQueryWrapperX<TblisustampMainDO> mainQuery = new LambdaQueryWrapperX<TblisustampMainDO>()
                .likeIfPresent(TblisustampMainDO::getCategory, reqVO.getKeyWord());
        if (StringUtils.isNotEmpty(reqVO.getKeyWord())) {
            mainQuery.or().like(TblisustampMainDO::getAgentCode, reqVO.getKeyWord());
            mainQuery.or().like(TblisustampMainDO::getPortCode, reqVO.getKeyWord());
        }
        List<TblisustampMainDO> mainList = tblisustampMainMapper.selectList(mainQuery);
        if (CollectionUtil.isNotEmpty(mainList)) {
            List<Long> mainIds = mainList.stream().map(vo -> vo.getId()).collect(Collectors.toList());
            itemQuery.in(TblisustampFilesDO::getMainId, mainIds);
        }
        return tblisustampFilesMapper.selectPage(reqVO, itemQuery);
    }

    @Override
    public void commitOrCancelApprove(RecordStatusDto recordStatusDto) throws Exception {
        Long itemId = recordStatusDto.getItemId();
        String status = recordStatusDto.getStatus();
        TblisustampFilesDO tblisustampFilesDO = tblisustampFilesMapper.selectById(itemId);
        if (tblisustampFilesDO == null) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.TBLISUSTAMP_FILES_NOT_EXISTS);
        }
        if(PENDING_APPROVE.getValue().toString().equals(status)){
            if(!PENDING_SUBMIT.getValue().toString().equals(tblisustampFilesDO.getRecordStatus())){
                throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_USER_NOT_ONE);
            }
            tblisustampFilesDO.setRecordStatus(PENDING_APPROVE.getValue());

        }else if(CANCEL.getValue().toString().equals(status)){
            if(!PENDING_SUBMIT.getValue().toString().equals(tblisustampFilesDO.getRecordStatus())){
                throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_USER_NOT_TWO);
            }
            tblisustampFilesDO.setRecordStatus(CANCEL.getValue());
        }else if(APPROVED.getValue().toString().equals(status)){
            if(!PENDING_APPROVE.getValue().toString().equals(tblisustampFilesDO.getRecordStatus())){
                throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_USER_NOT_THREE);
            }
            tblisustampFilesDO.setRecordStatus(APPROVED.getValue());
        }else if(REJECT.getValue().toString().equals(status)){
            if(!PENDING_APPROVE.getValue().toString().equals(tblisustampFilesDO.getRecordStatus())){
                throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_USER_NOT_FOUR);
            }
            tblisustampFilesDO.setRecordStatus(REJECT.getValue());
        }else{
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.ILLEGAL_STATUS);
        }
        tblisustampFilesMapper.updateById(tblisustampFilesDO);
    }

/*    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createApproval(TblisustampCreateApprovalVO req) {
        UserProfileDTO checkedData = nucApi.getUserProfile().getCheckedData();
        if (ObjectUtil.isEmpty(checkedData)) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_USER_NOT_FOUND);
        }
        TblisustampFilesDO entity = this.tblisustampFilesMapper.selectById(req.getId());
        if (ObjectUtil.isNull(entity)) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.TBLISUSTAMP_FILES_NOT_EXISTS);
        }
        if (entity.getRecordStatus() != PENDING_SUBMIT.getValue()) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_ERROR);
        }
        // 通过流程标识获取最新工作流定义
        ProcessDefinition processDefinition = bpmProcessDefinitionService.getActiveProcessDefinition(PROCESS_KEY);

        // 构建dto
        BpmProcessInstanceCreateReqDTO dto = new BpmProcessInstanceCreateReqDTO();
        dto.setProcessDefinitionId(processDefinition.getId());
        dto.setBusinessKey(String.valueOf(entity.getId()));

        Map<String, Object> variables = new HashMap<>(10);
        dto.setVariables(variables);
        //前端url 办理页面  
        variables.put(BpmConstants.APPROVAL_ROUTE_URL, "/doc/file-approve/detail");
        // 当前微服务项目url前缀
        variables.put("applicationPrefix", "/doc");
        variables.put(BpmConstants.APPROVAL_PAGE_OPEN_TYPE, BpmConstants.APPROVAL_PAGE_OPEN_TYPE_RUOTEJUMP);

        // 创建工作流实例
        String processInstanceId = bpmProcessInstanceAppService.create(dto);

        entity.setProcessinstanceId(processInstanceId);
        entity.setRecordStatus(PENDING_APPROVE.getValue());
        entity.setSubmitDate(LocalDateTime.now());
        entity.setSubmitBy(checkedData.getNickname());
        this.tblisustampFilesMapper.updateById(entity);
    }*/

/*    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelProcessInstance(TblisustampApproveCancelVO req) {
        TblisustampFilesDO entity = tblisustampFilesMapper.selectById(req.getId());
        if (ObjectUtil.isNull(entity)) {
            throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.TBLISUSTAMP_FILES_NOT_EXISTS);
        }
        entity.setCancelDate(LocalDateTime.now());
        entity.setRecordStatus(CANCEL.getValue());
        tblisustampFilesMapper.updateById(entity);

        BpmProcessInstanceCancelReqDTO dto = new BpmProcessInstanceCancelReqDTO();
        dto.setId(String.valueOf(entity.getProcessinstanceId()));
        dto.setReason(req.getReason());
        bpmProcessInstanceAppService.cancelProcessInstanceByStartUser(dto);
    }*/

    @Override
    public void updateLeaveStatus(long id, Integer status) {
        TblisustampFilesDO updateObj = new TblisustampFilesDO();
        updateObj.setId(id);
        updateObj.setRecordStatus(status);
        if (status == CANCEL.getValue()) {
            UserProfileDTO checkedData = nucApi.getUserProfile().getCheckedData();
            if (ObjectUtil.isEmpty(checkedData)) {
                throw ServiceExceptionUtil.exception(TblisustampFilesErrorCodeConstants.STATUS_USER_NOT_FOUND);
            }
            updateObj.setCancelDate(LocalDateTime.now());
            updateObj.setCancelBy(checkedData.getNickname());
        }
        tblisustampFilesMapper.updateById(updateObj);
    }
}
